using System.Diagnostics;
using System;

namespace TraumaticStudios.OpenOdeLibrary
{
    /// <summary>
    /// A generic ODE to be solved.
    /// </summary>
    public abstract class Ode : Microsoft.Xna.Framework.IUpdateable
    {
        /// <summary>
        /// Constructs a new ODE.
        /// </summary>
        /// <param name="numberOfEquations">The number of equations that must be solved.</param>
        protected Ode(int numberOfEquations)
        {
            dependantVariables = new double[numberOfEquations];
        }

        private double[] dependantVariables;

        /// <summary>
        /// The dependant variables.
        /// </summary>
        public double[] DependantVariables
        {
            [DebuggerStepThrough]
            get { return dependantVariables; }
        }

        private double time;

        /// <summary>
        /// The current time.
        /// </summary>
        public double Time
        {
            [DebuggerStepThrough]
            get { return time; }
            [DebuggerStepThrough]
            set { time = value; }
        }

        /// <summary>
        /// Evaluates the ODE.
        /// </summary>
        /// <param name="time">The current time.</param>
        /// <param name="dependantVariables">All the current dependant variables.</param>
        /// <param name="deltaDependantVariables">The delta of the dependant variables.</param>
        /// <param name="deltaTime">The delta of the time.</param>
        /// <param name="dependantVariableScale">The position between 0 and 1 of the RK evaluation.</param>
        /// <returns>The new dependant variables.</returns>
        public abstract double[] EvaluateRightHandSide(double time, double[] dependantVariables,
                                                  double[] deltaDependantVariables, double deltaTime,
                                                  double dependantVariableScale);

        #region IUpdateable Members
        private bool enabled = true;
        public bool Enabled
        {
            get { return enabled; }
            set { enabled = value; }
        }

        public event System.EventHandler EnabledChanged;
        [CLSCompliant(false)]
        public abstract void Update(Microsoft.Xna.Framework.GameTime gameTime);

        private int updateOrder = 0;
        public int UpdateOrder
        {
            get { return updateOrder; }
            set { updateOrder = value; }
        }

        public event System.EventHandler UpdateOrderChanged;

        #endregion
    }
}